package com.kunsan.compose.net

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.content.res.Configuration
import android.os.Build
import android.os.Parcelable
import android.provider.Settings
import android.telephony.TelephonyManager
import android.util.DisplayMetrics
import android.view.Display
import android.view.WindowManager
import com.google.gson.Gson
import com.tencent.mmkv.MMKV
import kotlinx.parcelize.Parcelize
import java.lang.reflect.Method
import java.util.*
import kotlin.math.pow
import kotlin.math.sqrt


object AppInternalInformation {

    /**
     * 设备Id
     */
    private const val KEY_DEVICE_ID = "key_device_id"
    private const val KEY_DEVICE_MODEL = "key_device_model"

    @SuppressLint("HardwareIds")
    fun getDeviceId(): String {
        MMKV.defaultMMKV().decodeString(KEY_DEVICE_ID)?.apply {
            return this
        }
        val id = try {
            Settings.Secure.getString(
                getCurApplication()?.contentResolver,
                Settings.Secure.ANDROID_ID
            )
        } catch (e: java.lang.Exception) {
            UUID.randomUUID().toString().replace("-", "")
        }
        MMKV.defaultMMKV().encode(KEY_DEVICE_ID, id)
        return id

    }

    fun getDeviceModel(): String {
        MMKV.defaultMMKV().decodeParcelable(KEY_DEVICE_MODEL, DeviceModel::class.java)?.apply {
            return Gson().toJson(this)
        }
        val device = DeviceModel(
            Build.MANUFACTURER,
            Build.MODEL,
            Build.DISPLAY
        )
        MMKV.defaultMMKV().encode(KEY_DEVICE_MODEL, device)
        return Gson().toJson(device)
    }

    private fun getTelephonyManager(context: Context): TelephonyManager? {
        return try {
            context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        } catch (e: Exception) {
            null
        }
    }

    fun isPhone(): Boolean {
        getCurApplication()?.apply {
            getTelephonyManager(this)?.let {
                return it.phoneType != TelephonyManager.PHONE_TYPE_NONE
            }
        }
        return false
    }

    fun isPad(): Boolean {
        getCurApplication()?.apply {
            val isPad: Boolean = (resources.configuration.screenLayout
                    and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE

            val wm: WindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val display: Display = wm.getDefaultDisplay()
            val dm = DisplayMetrics()
            display.getMetrics(dm)
            val x = (dm.widthPixels / dm.xdpi).toDouble().pow(2.0)
            val y = (dm.heightPixels / dm.ydpi).toDouble().pow(2.0)
            val screenInches = sqrt(x + y) // 屏幕尺寸
            return isPad || screenInches >= 7.0
        }
        return false
    }

    @SuppressLint("PrivateApi", "DiscouragedPrivateApi")
    private fun getCurApplication(): Application? {
        var application: Application? = null
        try {
            val atClass = Class.forName("android.app.ActivityThread")
            val currentApplicationMethod: Method = atClass.getDeclaredMethod("currentApplication")
            currentApplicationMethod.isAccessible = true
            application = currentApplicationMethod.invoke(null) as Application
        } catch (e: Exception) {
            e.printStackTrace()
        }
        if (application != null) return application
        try {
            val atClass = Class.forName("android.app.AppGlobals")
            val currentApplicationMethod: Method =
                atClass.getDeclaredMethod("getInitialApplication")
            currentApplicationMethod.isAccessible = true
            application = currentApplicationMethod.invoke(null) as Application
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return application
    }


    @Parcelize
    private data class DeviceModel(
        var manufactuere: String?, //品牌商、生产商（苹果、华为）
        var model: String?, //厂家内部的设备型号 (MLT93CH/A)
        var display: String?, //消费者显示的设备型号 (iPhone 13 Pro)
    ) : Parcelable
}